package com.water.quality.testing.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.water.quality.testing.dao.ObservationPoint;
import com.water.quality.testing.dao.WaterData;
import com.water.quality.testing.mapper.ObservationPointMapper;
import com.water.quality.testing.mapper.WaterDataMapper;
import com.water.quality.testing.service.WaterDataService;
import io.netty.util.internal.StringUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @author LYT0905
 * @Description:
 * @Date: 2024/06/23 13:26:27
 */
@Service
public class WaterDataServiceImpl extends ServiceImpl<WaterDataMapper, WaterData> implements WaterDataService {
    @Resource
    private WaterDataMapper waterDataMapper;
    @Resource
    private ObservationPointMapper observationPointMapper;

    /**
     * 根据水质id获取水质数据
     * @param id  水质id
     */
    @Override
    public List<WaterData> getWaterDataById(Long id) {
        LambdaQueryWrapper<WaterData> queryWrapper = Wrappers.lambdaQuery(WaterData.class)
                .eq(WaterData::getId, id);
        return baseMapper.selectList(queryWrapper);
    }

    /**
     * 获取所有水质数据（分页查询）
     * @param pageNum  当前页
     * @param pageSize 一页显示的数据条数
     * @param observationName  观测点名字（如果没使用根据观测点名字查询，默认空字符串）
     * @param start 开始时间（用于查询指定区间范围的水质数据， 不传默认为 null）
     * @param end  结束时间（用于查询指定区间范围的水质数据，不传默认为 null）
     */
    @Override
    public IPage<WaterData> getAllWaterData(Integer pageNum, Integer pageSize, String observationName, LocalDateTime start, LocalDateTime end) {
        IPage<WaterData> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<WaterData> queryWrapper = Wrappers.lambdaQuery(WaterData.class)
                // 如果观测点名字不为空字符串，就根据观测点名字分页查询
                .eq(!observationName.equals(""), WaterData::getObservationPointName, observationName)
                // 如果时间不为空，则拼接sql大于等于开始时间，小于等于结束时间
                .ge(start != null, WaterData::getCreatedAt, start)
                .le(end != null, WaterData::getCreatedAt, end);
        return waterDataMapper.selectPage(page, queryWrapper);
    }

    /**
     * 根据观测点名字查找该地区的水质数据
     * @param observationName 观测点名字
     */
    @Override
    public List<WaterData> getWaterByObservationPointName(String observationName) {
        // 条件构造器
        LambdaQueryWrapper<ObservationPoint> queryWrapper = Wrappers.lambdaQuery(ObservationPoint.class)
                .eq(ObservationPoint::getName, observationName);
        // 首先根据名字查找到该地区
        ObservationPoint observationPoint = observationPointMapper.selectOne(queryWrapper);
        LambdaQueryWrapper<WaterData> wrapper = Wrappers.lambdaQuery(WaterData.class)
                .eq(WaterData::getObservationPointId, observationPoint.getId());
        // 按照观测点id查找水质数据
        return waterDataMapper.selectList(wrapper);
    }

    /**
     * 获取观测点最后插入的一条数据（该方法是用在模拟数据时使用）
     * @param observationPointId  观测点id
     */
    @Override
    public WaterData getLatestWaterData(Long observationPointId) {
        return waterDataMapper.findTopByObservationPointIdOrderByIdDesc(observationPointId);
    }

    /**
     * 新增水质数据（该方法是用在模拟数据时使用）
     * @param waterData 水质数据实体类
     */
    @Override
    public void saveWaterData(WaterData waterData) {
        waterDataMapper.insert(waterData);
    }

    /**
     * 根据水质数据id或者按照某个时间节点进行删除（删除时间节点之前的数据）
     * @param id  水质数据id
     * @param start  时间节点
     */
    @Override
    public void deleteWaterData(String id, LocalDateTime start) {
        LambdaUpdateWrapper<WaterData> updateWrapper = Wrappers.lambdaUpdate(WaterData.class)
                .eq(!StringUtil.isNullOrEmpty(id), WaterData::getId, id)
                .le(start != null, WaterData::getCreatedAt, start);
        baseMapper.delete(updateWrapper);
    }
}
